package com.blackcat.core;

import org.apache.commons.lang3.StringUtils;
import org.jaudiotagger.audio.AudioFile;
import org.jaudiotagger.audio.AudioFileIO;
import org.jaudiotagger.tag.Tag;
import org.jaudiotagger.tag.FieldKey;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 标签信息读取
 * @author : zhangdahui  2024/9/6 下午4:09
 */

@Component
public class MusicTagReader {

    private static final String suffix = ",";
    private static final String left = "left";
    private static final String open = "true";
    private static final String separator = File.separator;

    @Value("${read-path}")
    private String readPath;
    @Value("${archive-path}")
    private String archivePath;
    @Value("${ignore-directory}")
    private String ignoreDirectory;
    @Value("${file-name-partition}")
    private String partition;
    @Value("${file-name-singer-position}")
    private String singerPosition;
    @Value("${classification-album}")
    private String classificationAlbum;
    @Value("${classification-singer}")
    private String classificationSinger;
    @Value("${rename-open}")
    private String rename;
    @Value("${rename-partition}")
    private String renamePartition;
    @Value("${rename-singer-position}")
    private String renameSingerPosition;
    @Value("${delete-open}")
    private String delete;

    public void start(){
        List<String> ignoreDirectoryList = new ArrayList<>();
        if (StringUtils.isNotBlank(ignoreDirectory)) {
            ignoreDirectoryList = Arrays.asList(ignoreDirectory.split(suffix));
        }
        // 处理配置文件中路径可能带有中文处理
        readPath = new String(readPath.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
        archivePath = new String(archivePath.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
        // 读取文件
        readFile(readPath, ignoreDirectoryList);
    }

    /**
     * 描述 :   读取文件夹问文件信息
     * @author : zhangdahui 2024/9/9 上午10:02
     * @param path 文件夹路径
     * @param ignoreDirectoryList  忽略指定名称文件夹
    */
    public void readFile(String path,List<String> ignoreDirectoryList) {
        File file = new File(path);
        if (file.exists()) {
            if (!file.isDirectory()) {
                readTag(file);
            } else if (file.isDirectory()) {
                if(!ignoreDirectoryList.contains(file.getName())){
                    String[] fileList = file.list();
                    if (fileList != null) {
                        for (String name : fileList) {
                            File readFile = new File(path + separator + name);
                            if (!readFile.isDirectory()) {
                                readTag(readFile);
                            } else if (readFile.isDirectory()) {
                                if(!ignoreDirectoryList.contains(readFile.getName())){
                                    readFile(path + separator + name, ignoreDirectoryList);
                                }
                            }
                        }
                    }
                }
            }
        }else {
            System.out.println("文件路径不存在！" + path);
        }
    }

    /**
     * 描述 :   读取文件标签信息
     * @author : zhangdahui 2024/9/9 上午10:01
     * @param file  文件
    */
    private void readTag(File file){
        try {
            String fileName = file.getName();
            String suffix = getSuffix(fileName);
            fileName = fileName.replace("." + suffix, "");
            String title = null;
            String artist = null;
            String album = null;
            // AudioFile支持格式：ogg、mp3、flac、mp4、m4a、m4p、wma、wav、ra、rm、m4b
            // 如果你需要读取 MP4 文件的标签，请确保 MP4 文件只包含音频流。jaudiotagger 不支持带视频的 MP4 文件，因此可能会报错。
            // 这里无法判断 MP4 文件是否只包含音频流，所以不读取 MP4 格式文件。
            if (StringUtils.equalsAnyIgnoreCase(suffix, "mp3", "flac", "wav")) {
                // 读取音乐文件
                AudioFile audioFile = AudioFileIO.read(file);
                // 获取标签信息
                Tag tag = audioFile.getTag();
                title = tag.getFirst(FieldKey.TITLE);//歌曲名称
                artist = tag.getFirst(FieldKey.ARTIST);//艺术家、歌手
                album = tag.getFirst(FieldKey.ALBUM);//专辑
            }

            // 标签中没有刮削信息，读取文件名称
            if (StringUtils.isBlank(title) || StringUtils.isBlank(artist)) {
                // 文件名包含分隔符
                if (fileName.contains(partition)) {
                    String[] strings = fileName.split(partition);
                    if (strings.length == 2) {
                        if (left.equals(singerPosition)) {
                            if (StringUtils.isBlank(title)) {
                                title = strings[1].trim();
                            }
                            if (StringUtils.isBlank(artist)) {
                                artist = strings[0].trim();
                            }
                        } else {
                            if (StringUtils.isBlank(title)) {
                                title = strings[0].trim();
                            }
                            if (StringUtils.isBlank(artist)) {
                                artist = strings[1].trim();
                            }
                        }
                    }
                } else {
                    title = fileName;
                }
            }

            System.out.println("标题: " + title);
            System.out.println("歌手: " + artist);
            System.out.println("专辑: " + album);
            // 是否创建专辑文件夹
            if (open.equals(classificationAlbum) && StringUtils.isNotBlank(album)) {
                File albumDirectory = new File(archivePath + separator + "专辑" + separator + artist + separator + album);
                if (!albumDirectory.exists()) {
                    albumDirectory.mkdirs();
                }
                // 复制文件
                fileCopy(file.getAbsolutePath(),albumDirectory + separator + rename(artist,title,file.getName()));
            }
            // 是否创建歌手文件夹
            if (open.equals(classificationSinger) && StringUtils.isNotBlank(artist)) {
                File artistDirectory = new File(archivePath + separator + "歌手" + separator + artist);
                if (!artistDirectory.exists()) {
                    artistDirectory.mkdirs();
                }
                // 复制文件
                fileCopy(file.getAbsolutePath(),artistDirectory + separator + rename(artist,title,file.getName()));
            }
            if (open.equals(delete)) {
                // 删除源文件
                file.delete();
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 描述 :   文件重命名
     * @author : zhangdahui 2024/9/9 上午10:42
     * @param artist 艺术家、歌手
     * @param title 歌名
     * @param fileName  文件原名
    */
    private String rename(String artist, String title,String fileName){
        if (open.equals(rename)) {
            String suffix = getSuffix(fileName);
            if (left.equals(renameSingerPosition)){
                return artist + renamePartition + title + "." + suffix;
            }else {
                return title + renamePartition + artist + "." + suffix;
            }
        }
        return fileName;
    }

    /**
     * 描述 :   文件复制
     * @author : zhangdahui 2024/9/7 上午12:32
     * @param source 源文件全路径
     * @param target 复制地址文件路径
    */
    private void fileCopy(String source, String target){
        try {
            // 创建一个带缓冲区的输入流
            BufferedInputStream bis = new BufferedInputStream(Files.newInputStream(Paths.get(source)));
            // 创建一个带缓冲区的输出流
            BufferedOutputStream bos = new BufferedOutputStream(Files.newOutputStream(Paths.get(target)));
            // 定义一个字节数组，作为缓冲区
            byte[] buff = new byte[1024];
            int len;
            while ((len = bis.read(buff)) != -1) {
                bos.write(buff, 0, len); // 从第一个字节开始，向文件写入len个字节
            }
            bis.close();
            bos.close();
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 描述 :   截取文件后缀名
     * @author : zhangdahui 2024/9/7 上午12:07
     * @param fileName  文件名
    */
    private String getSuffix(String fileName){
        return fileName.substring(fileName.lastIndexOf(".") + 1);
    }

    public static void main(String[] args) {
        try {
            String path = "/Users/blackcat/Downloads/test-music/";
            // 指定音乐文件的路径
            File file = new File(path + "1-《呼兰河传》第一章（一）第二话商铺和学堂.mp3");

            // 读取音乐文件
            AudioFile audioFile = AudioFileIO.read(file);

            // 获取标签信息
            Tag tag = audioFile.getTag();

            // 获取常见的标签字段
            String title = tag.getFirst(FieldKey.TITLE);//歌曲名称
            String artist = tag.getFirst(FieldKey.ARTIST);//艺术家、歌手
            String album = tag.getFirst(FieldKey.ALBUM);//专辑
            String year = tag.getFirst(FieldKey.YEAR);//年份

            // 输出标签信息
            System.out.println("Title: " + title);
            System.out.println("Artist: " + artist);
            System.out.println("Album: " + album);
            System.out.println("Year: " + year);

        } catch (Exception e) {
            e.printStackTrace();
        }

//        常见的标签字段
//
//	•	ARTIST：歌手或艺术家
//	•	ALBUM：专辑名称
//	•	TITLE：歌曲名称
//	•	TRACK：曲目编号
//	•	YEAR：发行年份
//	•	GENRE：音乐流派
//	•	COMMENT：评论或备注
//	•	ALBUM_ARTIST：专辑的主艺人
//	•	COMPOSER：作曲者
//	•	GROUPING：分组信息（如专辑内的特定分组）
//	•	DISC_NO：光盘编号
//	•	COVER_ART：专辑封面图片
//
//                高级标签字段
//
//	•	BPM：每分钟节拍数
//	•	MUSICBRAINZ_ARTISTID：MusicBrainz 中的艺人 ID
//	•	MUSICBRAINZ_RELEASEID：MusicBrainz 中的发行 ID
//	•	MUSICBRAINZ_TRACK_ID：MusicBrainz 中的曲目 ID
//	•	MUSICIP_ID：MusicIP 的音频指纹 ID
//	•	AMAZON_ID：亚马逊的商品 ID
//
//        其他常见标签
//
//	•	IS_COMPILATION：是否为合辑
//	•	ENCODER：编码器信息
//	•	ISRC：国际标准录音代码
//	•	BARCODE：条形码
//	•	RECORD_LABEL：唱片公司
//
//        URL 和引用
//
//	•	URL_OFFICIAL_RELEASE_SITE：官方发行网站
//	•	URL_DISCOGS_RELEASE_SITE：Discogs 上的发行信息
//	•	URL_WIKIPEDIA_RELEASE_SITE：Wikipedia 上的发行信息
//	•	URL_OFFICIAL_ARTIST_SITE：艺术家官方主页
//	•	URL_DISCOGS_ARTIST_SITE：Discogs 上的艺术家主页
//	•	URL_WIKIPEDIA_ARTIST_SITE：Wikipedia 上的艺术家主页
//
//        语言、歌词和排序
//
//	•	LANGUAGE：歌曲语言
//	•	LYRICS：歌词
//	•	LYRICIST：作词者
//	•	ARTIST_SORT：用于排序的歌手名
//	•	ALBUM_SORT：用于排序的专辑名
//	•	TITLE_SORT：用于排序的歌曲名
//	•	COMPOSER_SORT：用于排序的作曲者名
    }


}
